module divide3(
		input [15:0]data1,
		input [15:0]data2,
		input [2:0]enable,
		input isNeg1,
		input isNeg2,
		input [1:0] pPos1,
		input [1:0] pPos2,	
		input done,
		input reset,
		input sysclk,
		output reg [15:0]result,
		output reg isNeg,
		output reg [1:0] pPosRes,
		output reg suc); 

reg [51:0] diff;
reg [25:0] data1_temp;
reg [25:0] data2_temp;
reg [26:0] s;
reg [25:0] result1;
reg [51:0] temp;
reg [4:0] counter;
reg [2:0] state;
reg [2:0] nstate;


reg [3:0] highPos_result;

parameter init = 3'b000, 
	  start = 3'b001, 
	  shift = 3'b010, 
	  waiting = 3'b011, 
	  finish = 3'b100;

initial begin
	diff = 52'b0;
	data1_temp = 26'b0;
	data2_temp = 26'b0;
	temp = 52'b0;
	counter = 5'd0;
	s = 27'b0;
	result = 16'b0;
	suc = 1'b0;
	nstate = init;
	end
		
		

always @(*) begin
	state = nstate;
end
		
		
always @(posedge sysclk) begin
	if (reset) begin
		diff = 46'b0;
		data1_temp = 23'b0;
		data2_temp = 23'b0;
		temp = 46'b0;
		s = 24'b0;
		counter = 5'd0;
		result = 16'b0;
		suc = 1'b0;
		nstate = state;
		end
	else begin
		case (state)
			init: begin
				if (enable==3'b101) begin
					diff = 52'b0;
					data1_temp = 26'b0;
					data2_temp = 26'b0;
					temp = 52'b0;
					s = 27'b0;
					result = 16'b0;
					counter = 5'd0;
					suc = 1'b0;
					nstate = start;
					end
				else 
					nstate = init;
			     	end
			
					
			start: begin
				data1_temp = data1*1000;
				data2_temp = {10'b0,data2};
				temp = {26'b0,data1_temp};
				s = {1'b1,~data2_temp+1'b1};
				nstate = shift;
			       end
			shift: begin
				if (counter<5'd26) begin
					diff = temp + {s,25'b0};
					if (diff[51]) 
						temp = {temp[50:0],1'b0};
					else 
						temp = {diff[50:0],1'b1};
					counter = counter + 1'b1;
					nstate = shift;
					end
				else begin
					isNeg = isNeg1 ^ isNeg2;
					result1 = temp[25:0];
					nstate = waiting;
					
					
					if (result1 > 25'd999_999)
						highPos_result = 7;
					else if (result1 > 25'd99_999)
						highPos_result = 6;
					else if (result1 > 25'd9_999)
						highPos_result = 5;
					else if (result1 > 25'd999)
						highPos_result = 4;
					else if (result1 > 25'd99)
						highPos_result = 3;
					else if (result1 > 25'd9)
						highPos_result = 2;
					else if (result1 > 25'd0)
						highPos_result = 1;
					else
						highPos_result = 0;
						
								

					if( pPos1 >= pPos2) begin
						case (pPos1 - pPos2)
							2'd0: begin 
									case (highPos_result)
										4'd7:begin
											pPosRes = 2'd0;
											result1 = ( ( (result1>>1) + (result1>>7)+ (result1>>8)+ (result1>>12)+ (result1>>15)+ (result1>>16)) >>9 ); 
											end
										4'd6:begin
											pPosRes = 2'd1;
											result1 = ( ( (result1>>1) + (result1>>3)+ (result1>>7)+ (result1>>8)+ (result1>>9)+ (result1>>10)+ (result1>>12)+ (result1>>14)+ (result1>>15)+ (result1>>16)+ (result1>>17) )  >>6 );
											end
										4'd5:begin
											pPosRes = 2'd2;
											result1 = ( ( (result1>>1) + (result1>>2)+ (result1>>5)+ (result1>>6)+ (result1>>9)+ (result1>>10)+ (result1>>12)) >>3 );
											end
										4'd4:begin
											pPosRes = 2'd3;
											end
										4'd3:begin
											pPosRes = 2'd3;
											end
										4'd2:begin
											pPosRes = 2'd3;
											end
										4'd1:begin
											pPosRes = 2'd3;
											end
										4'd0:begin
											result1 = 0;
											pPosRes = 2'd0;
											end
									endcase
								end
							2'd1: begin 
									case (highPos_result)
										4'd7:begin
											pPosRes = 2'd1;
											result1 = ( ( (result1>>1) + (result1>>7)+ (result1>>8)+ (result1>>12)+ (result1>>15)+ (result1>>16)) >>9 ); 
											end
										4'd6:begin
											pPosRes = 2'd2;
											result1 = ( ( (result1>>1) + (result1>>3)+ (result1>>7)+ (result1>>8)+ (result1>>9)+ (result1>>10)+ (result1>>12)+ (result1>>14)+ (result1>>15)+ (result1>>16)+ (result1>>17) )  >>6 );
											end
										4'd5:begin
											pPosRes = 2'd3;
											result1 = ( ( (result1>>1) + (result1>>2)+ (result1>>5)+ (result1>>6)+ (result1>>9)+ (result1>>10)+ (result1>>12)) >>3 );
											end
										4'd4:begin
											pPosRes = 2'd3;
											result1 = ( ( (result1>>1) + (result1>>2)+ (result1>>5)+ (result1>>6)+ (result1>>9)+ (result1>>10)+ (result1>>12)) >>3 );
											end
										4'd3:begin
											pPosRes = 2'd3;
											result1 = ( ( (result1>>1) + (result1>>2)+ (result1>>5)+ (result1>>6)+ (result1>>9)+ (result1>>10)+ (result1>>12)) >>3 );
											end
										4'd2:begin
											pPosRes = 2'd3;
											result1 = ( ( (result1>>1) + (result1>>2)+ (result1>>5)+ (result1>>6)+ (result1>>9)+ (result1>>10)+ (result1>>12)) >>3 );
											end
										4'd1:begin
											result1 = 0;
											pPosRes = 2'd0;
											end
										4'd0:begin
											result1 = 0;
											pPosRes = 2'd0;
											end
									endcase
								end
							2'd2: begin 
									case (highPos_result)
										4'd7:begin
											pPosRes = 2'd3;
											result1 = ( ( (result1>>1) + (result1>>7)+ (result1>>8)+ (result1>>12)+ (result1>>15)+ (result1>>16)) >>9 ); 
											end
										4'd6:begin
											pPosRes = 2'd3;
											result1 = ( ( (result1>>1) + (result1>>3)+ (result1>>7)+ (result1>>8)+ (result1>>9)+ (result1>>10)+ (result1>>12)+ (result1>>14)+ (result1>>15)+ (result1>>16)+ (result1>>17) )  >>6 );
											end
										4'd5:begin
											pPosRes = 2'd3;
											result1 = ( ( (result1>>1) + (result1>>3)+ (result1>>7)+ (result1>>8)+ (result1>>9)+ (result1>>10)+ (result1>>12)+ (result1>>14)+ (result1>>15)+ (result1>>16)+ (result1>>17) )  >>6 );
											end
										4'd4:begin
											pPosRes = 2'd3;
											result1 = ( ( (result1>>1) + (result1>>3)+ (result1>>7)+ (result1>>8)+ (result1>>9)+ (result1>>10)+ (result1>>12)+ (result1>>14)+ (result1>>15)+ (result1>>16)+ (result1>>17) )  >>6 );
											end
										4'd3:begin
											pPosRes = 2'd3;
											result1 = ( ( (result1>>1) + (result1>>3)+ (result1>>7)+ (result1>>8)+ (result1>>9)+ (result1>>10)+ (result1>>12)+ (result1>>14)+ (result1>>15)+ (result1>>16)+ (result1>>17) )  >>6 );
											end
										4'd2, 4'd1, 4'd0:begin
											result1 = 0;
											pPosRes = 2'd0;
											end
									endcase
								end
							2'd3: begin 
								case (highPos_result)
										4'd7:begin
											pPosRes = 2'd3;
											result1 = ( ( (result1>>1) + (result1>>7)+ (result1>>8)+ (result1>>12)+ (result1>>15)+ (result1>>16)) >>9 ); 
											end
										4'd6:begin
											pPosRes = 2'd3;
											result1 = ( ( (result1>>1) + (result1>>7)+ (result1>>8)+ (result1>>12)+ (result1>>15)+ (result1>>16)) >>9 ); 
											end
										4'd5:begin
											pPosRes = 2'd3;
											result1 = ( ( (result1>>1) + (result1>>7)+ (result1>>8)+ (result1>>12)+ (result1>>15)+ (result1>>16)) >>9 ); 
											end
										4'd4:begin
											pPosRes = 2'd3;
											result1 = ( ( (result1>>1) + (result1>>7)+ (result1>>8)+ (result1>>12)+ (result1>>15)+ (result1>>16)) >>9 ); 
											end
										4'd3, 4'd2, 4'd1, 4'd0:begin
											result1 = 0;
											pPosRes = 2'd0;
											end
									endcase
								end
						endcase 
					end else begin
					
						case (pPos2 - pPos1)
							
							2'd1: begin 
									case (highPos_result)
										4'd7:begin
											pPosRes = 2'd0;
											result1 = ( ( (result1>>1) + (result1>>7)+ (result1>>8)+ (result1>>12)+ (result1>>15)+ (result1>>16)) >>9 ); 
											end
										4'd6:begin
											pPosRes = 2'd0;
											result1 = ( ( (result1>>1) + (result1>>3)+ (result1>>7)+ (result1>>8)+ (result1>>9)+ (result1>>10)+ (result1>>12)+ (result1>>14)+ (result1>>15)+ (result1>>16)+ (result1>>17) )  >>6 );
											end
										4'd5:begin
											pPosRes = 2'd1;
											result1 = ( ( (result1>>1) + (result1>>2)+ (result1>>5)+ (result1>>6)+ (result1>>9)+ (result1>>10)+ (result1>>12)) >>3 );
											end
										4'd4:begin
											pPosRes = 2'd2;
											end
										4'd3:begin
											pPosRes = 2'd2;
											end
										4'd2:begin
											pPosRes = 2'd2;
											end
										4'd1:begin
											pPosRes = 2'd2;
											end
										4'd0:begin
											result1 = 0;
											pPosRes = 2'd0;
											end
									endcase
								end
							2'd2: begin 
									case (highPos_result)
										4'd7:begin
											pPosRes = 2'd0;
											result1 = ( ( (result1>>1) + (result1>>7)+ (result1>>8)+ (result1>>12)+ (result1>>15)+ (result1>>16)) >>9 ); 
											end
										4'd6:begin
											pPosRes = 2'd0;
											result1 = ( ( (result1>>1) + (result1>>3)+ (result1>>7)+ (result1>>8)+ (result1>>9)+ (result1>>10)+ (result1>>12)+ (result1>>14)+ (result1>>15)+ (result1>>16)+ (result1>>17) )  >>6 );
											end
										4'd5:begin
											pPosRes = 2'd0;
											result1 = ( ( (result1>>1) + (result1>>2)+ (result1>>5)+ (result1>>6)+ (result1>>9)+ (result1>>10)+ (result1>>12)) >>3 );
											end
										4'd4:begin
											pPosRes = 2'd1;
											end
										4'd3:begin
											pPosRes = 2'd1;
											end
										4'd2, 4'd1: begin
											pPosRes = 2'd1;
											end
										4'd0:begin
											result1 = 0;
											pPosRes = 2'd0;
											end
									endcase
								end
							2'd3: begin 
								case (highPos_result)
										4'd7:begin
											pPosRes = 2'd0;
											result1 = ( ( (result1>>1) + (result1>>7)+ (result1>>8)+ (result1>>12)+ (result1>>15)+ (result1>>16)) >>9 ); 
											end
										4'd6:begin
											pPosRes = 2'd0;
											result1 = ( ( (result1>>1) + (result1>>3)+ (result1>>7)+ (result1>>8)+ (result1>>9)+ (result1>>10)+ (result1>>12)+ (result1>>14)+ (result1>>15)+ (result1>>16)+ (result1>>17) )  >>6 );
											end
										4'd5:begin
											pPosRes = 2'd0;
											result1 = ( ( (result1>>1) + (result1>>2)+ (result1>>5)+ (result1>>6)+ (result1>>9)+ (result1>>10)+ (result1>>12)) >>3 ); 
											end
										4'd4:begin
											pPosRes = 2'd0;
											end
										4'd3, 4'd2, 4'd1: begin
											pPosRes = 2'd0;
											end
										4'd0:begin
											result1 = 0;
											pPosRes = 2'd0;
											end
									endcase
								end
						endcase 
						end
					end
				end
						
			waiting: begin
					result = result1[15:0];
					suc = 1'b1;
					nstate = finish;
				end
			
			finish: begin
				if (done) begin
					suc = 1'b0;
					nstate = init;
					end
				else 
					nstate = finish;
				end
		
		endcase
	end
end


endmodule
